﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Baosight.Platform.Core;
using Baosight.Platform.Core.UI.Controls;
using Baosight.Platform.Core.ServiceModel;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Charting;
using Baosight.ZNH.ZMCA.UI.Model;
using Baosight.ZNH.ZMCA.UI.Utils;


namespace Baosight.ZNH.ZMCA.UI
{
    public partial class ZMCA22 : EFView
    {
        private IList<string> selectDepartments = new List<string>();

        public ZMCA22()
        {
            InitializeComponent();
            this.dataPicker.ShowEngineering(false);
            this.dataPicker.SetEngineeringOrgAllItem(false);
            dataPicker.ShowEngineeringName = System.Windows.Visibility.Collapsed;
        }

        /// <summary>
        /// "分析"按钮事件响应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public override void OnQueryButtonClick(object sender, RoutedEventArgs e)
        {
            //analysisType：0总体趋势图，1单位对比图，2工程对比图
            string analysisType = "0";

            if (dataPicker.IsCheckedAllOrg())//选择了全部单位
            {
                if (dataPicker.GetEngineeringName().Count == 1)
                {
                    analysisType = "0";//只选择了一个工程
                }
                else if (!dataPicker.IsCheckedAllEngineering())
                {
                    analysisType = "2";//选择了多个工程
                }
            }
            else//没有选择全部单位
            {
                if (dataPicker.IsCheckedAllEngineering())//选择全部工程
                {
                    if (dataPicker.GetEngineeringOrg().Count == 1)
                    {
                        analysisType = "0";//只选择了一个单位
                    }
                    else
                    {
                        analysisType = "1";//选择了多个单位
                    }
                }
                else
                {
                    if (dataPicker.GetEngineeringName().Count == 1)
                    {
                        analysisType = "0";//只选择了一个工程
                    }
                    else if (!dataPicker.IsCheckedAllEngineering())
                    {
                        analysisType = "2";//选择了多个工程
                    }
                }
            }

            switch (analysisType)
            {
                case "0":
                    ShowTrendChart();
                    break;
                case "1":
                    ShowDepartmentComparationChart();
                    break;
                default:
                    //ShowProjectComparationChart();
                    break;
            }
        }

        #region 全矿综合指标趋势分析图数据查询，及数据处理

        /// <summary>
        /// 趋势图查询
        /// </summary>
        private void ShowTrendChart()
        {
            Chart.Visibility = System.Windows.Visibility.Collapsed;
            EIInfo eiInfo = new EIInfo();
            eiInfo.Set(EIConstants.ServiceNameKey, "ZMCA22");
            eiInfo.Set(EIConstants.MethodNameKey, "queryByTrend");

            EIBlock inqu = eiInfo.AddBlock(EIConstants.QueryStatusBlock);
            Common.AddEIColumnsToEIBlock(inqu, new string[] { "fdToYear", "fdToMonth", "fdFromYear", "fdFromMonth", 
                "fdProjectType", "fdDepartmentIds", "fdProjectIds" });
            EIRow row = initQueryRow();
            inqu.AddRow(row);

            HttpServiceAgent agent = new HttpServiceAgent();
            agent.CallService(eiInfo, QueryByTrendDoWorkCompleted);
        }

        /// <summary>
        /// 趋势图查询回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryByTrendDoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
        {
            if (e.EIInfo.Status == -1)
            {
                return;
            }
            else
            {
                EIInfo outInfo = e.EIInfo;

                int currentYear = Common.GetIntValue(outInfo.Get("year"));
                int currentMonth = Common.GetIntValue(outInfo.Get("month"));

                EIBlock config = outInfo.GetBlock("config");    
                EIBlock securityCount = outInfo.GetBlock("securityCount");
                EIBlock produceCount = outInfo.GetBlock("produceCount");
                EIBlock producePlanRate = outInfo.GetBlock("producePlanRate");
                EIBlock materialPlanRate = outInfo.GetBlock("materialPlanRate");

                EIRow inqu = outInfo.GetBlock(EIConstants.QueryStatusBlock).GetRow(0);
                int fdFromYear = Common.GetIntValue(inqu["fdFromYear"]);
                int fdFromMonth = Common.GetIntValue(inqu["fdFromMonth"]);
                int fdToYear = Common.GetIntValue(inqu["fdToYear"]);
                int fdToMonth = Common.GetIntValue(inqu["fdToMonth"]);

                InitChart("TREND");

                List<List<ChartData>> itemsSource = new List<List<ChartData>>();
                List<ChartData> lstIndex = new List<ChartData>();
                IDictionary<string, ChartData> dic = new Dictionary<string, ChartData>();   //使用Dictionary帮助后面填充值

                //构造年月横坐标
                for (int y = fdFromYear, m = fdFromMonth; y < fdToYear || (y == fdToYear && m <= fdToMonth); )
                {
                    ChartData cd = new ChartData(y + "-" + m, 100);
                    lstIndex.Add(cd);
                    dic.Add(cd.Date, cd);

                    m++;
                    if (m == 13)
                    {
                        y++;
                        m = 1;
                    }
                }

                decimal weight = GetConfig(config, "7");                  // 7: 安全问题权重; 
                GetIndexValue(dic, securityCount, weight, "fdKeyId", "");     //安全问题数量指标

                weight = GetConfig(config, "8");                         //8: 生产问题权重;
                GetIndexValue(dic, produceCount, weight, "fdKeyId", "");     //生产问题的数量指标

                weight = GetConfig(config, "9");                        //9:生产计划偏差率权重;
                GetIndexValue(dic, producePlanRate, weight, "fdRate", "SUB");  //生产计划偏差率指标

                weight = GetConfig(config, "10");                       // 10: 材料计划超节率权重
                GetIndexValue(dic, materialPlanRate, weight, "fdRate", "PLUS");  //材料计划超节率权重

                itemsSource.Add(lstIndex);
                Chart.ItemsSource = itemsSource;
                Chart.Visibility = System.Windows.Visibility.Visible;
            }
 
        }

        /// <summary>
        /// 初始化查询条件
        /// </summary>
        /// <returns></returns>
        private EIRow initQueryRow()
        {
            IList<EIRow> selectedDepartments = dataPicker.GetEngineeringOrg();

            string departments = "''";
            selectDepartments.Clear();

            foreach (var item in selectedDepartments)
            {
                departments = departments + ",'" + item["orgCode"].ToString() + "'";
                selectDepartments.Add(item["orgCode"].ToString());
            }

            IList<EIRow> selectedProjects = dataPicker.GetEngineeringName();
            string projects = "''";
            foreach (var item in selectedProjects)
            {
                projects = projects + ",'" + item["fdKeyId"].ToString() + "'";
            }

            EIRow conRow = new EIRow();
            conRow.Add("fdFromYear", datePicker.FromDate.Year.ToString());
            conRow.Add("fdFromMonth", datePicker.FromDate.Month.ToString());
            conRow.Add("fdToYear", datePicker.ToDate.Year.ToString());
            conRow.Add("fdToMonth", datePicker.ToDate.Month.ToString());
            conRow.Add("fdProjectType", GetProjectTypeName());
            conRow.Add("fdDepartmentIds", departments);
            conRow.Add("fdProjectIds", projects);
            return conRow;
        }

        /// <summary>
        /// 工程类型只有采煤计划，掘进计划和开拓计划3种
        /// </summary>
        /// <returns></returns>
        private string GetProjectTypeName()
        {
            string projectType = dataPicker.GetEngineeringType();

            switch (projectType)
            {
                case "0":
                    return "采煤计划";
                case "1":
                    return "掘进计划";
                default:
                    return "掘进计划";
            }
        }

        /// <summary>
        /// 获取各个指标的权重
        /// </summary>
        /// <param name="config"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private decimal GetConfig(EIBlock config, string index)
        {
            var result = from item in config.Rows where item["fdKeyId"].ToString().Trim() == index select item["fdRate"].ToString();
            string val = result.ElementAtOrDefault(0).Trim();

            if (val != null || (!"".Equals(val.Trim())))
                return Convert.ToDecimal(val);
            else
                return 0;
        }

        /// <summary>
        /// 趋势图，获取各个指标值*权重结果
        /// </summary>
        /// <param name="dic"></param>
        /// <param name="block"></param>
        /// <param name="weight"></param>
        /// <param name="index"></param>
        private void GetIndexValue(IDictionary<string, ChartData> dic, EIBlock block, decimal weight, string index, string type)
        {
            foreach (var item in block.Rows)
            {
                if ((item["fdYear"] == null) || (item["fdYear"].ToString().Trim() == string.Empty) ||
                    (item["fdMonth"] == null) || (item["fdMonth"].ToString().Trim() == string.Empty))
                {
                    continue;
                }

                string month = item["fdMonth"].ToString().Trim().TrimStart('0');
                string year = item["fdYear"].ToString();
                string date = year + "-" + month;

                decimal val = Common.GetDecimalValue(item[index]);

                if (index.Equals("fdKeyId"))
                {
                    dic[date].DataValue += val * weight;
                }
                else if (index.Equals("fdRate"))
                {
                    if (type.Equals("PLUS"))    //生产计划偏差率
                    {
                        decimal actualSum = Common.GetDecimalValue(item["fdActualSum"]);
                        decimal planSum = Common.GetDecimalValue(item["fdPlanSum"]);

                        val = planSum <= Decimal.Zero ? Decimal.Zero : (Math.Abs(1 - actualSum / planSum) * 100);
                        dic[date].DataValue += val * weight;
                    }
                    else if (type.Equals("SUB"))    //材料消耗超节率
                    {
                        decimal actualSum = Common.GetDecimalValue(item["fdActualSum"]);
                        decimal planSum = Common.GetDecimalValue(item["fdPlanSum"]);

                        val = planSum <= Decimal.Zero ? Decimal.Zero : (Math.Abs(actualSum / planSum - 1) * 100);
                        dic[date].DataValue += val * weight;
                    }
                }


                
            }
        }

        #endregion

        #region 工程单位生产综合指标对比图

        /// <summary>
        /// 工程单位对比图查询
        /// </summary>
        private void ShowDepartmentComparationChart()
        {
            Chart.Visibility = System.Windows.Visibility.Collapsed;
            EIInfo eiInfo = new EIInfo();
            eiInfo.Set(EIConstants.ServiceNameKey, "ZMCA22");
            eiInfo.Set(EIConstants.MethodNameKey, "queryByDepartment");

            EIBlock inqu = eiInfo.AddBlock(EIConstants.QueryStatusBlock);
            Common.AddEIColumnsToEIBlock(inqu, new string[] { "fdToYear", "fdToMonth", "fdFromYear", "fdFromMonth", 
                "fdProjectType", "fdDepartmentIds", "fdProjectIds" });
            EIRow row = initQueryRow();
            inqu.AddRow(row);

            HttpServiceAgent agent = new HttpServiceAgent();
            agent.CallService(eiInfo, QueryByDepartmentDoWorkCompleted);
        }

        /// <summary>
        /// 工程单位对比图查询回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryByDepartmentDoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
        {
            if (e.EIInfo.Status == -1)
            {
                return;
            }
            else
            {
                EIInfo outInfo = e.EIInfo;

                EIBlock config = outInfo.GetBlock("config");    //各个指标权重
                EIBlock securityCount = outInfo.GetBlock("securityCount");
                EIBlock produceCount = outInfo.GetBlock("produceCount");
                EIBlock producePlanRate = outInfo.GetBlock("producePlanRate");
                EIBlock materialPlanRate = outInfo.GetBlock("materialPlanRate");

                int currentYear = Common.GetIntValue(outInfo.Get("year").ToString());
                int currentMonth = Common.GetIntValue(outInfo.Get("month").ToString());

                InitChart("DEPARTMENT");

                List<List<ChartData>> itemsSource = new List<List<ChartData>>();
                List<ChartData> lstIndex = new List<ChartData>();
                IDictionary<string, EIRow> dic = new Dictionary<string, EIRow>();   //使用Dictionary帮助后面填充值

                decimal weight = GetConfig(config, "7");
                IList<EIRow> securityCountList = securityCount.GetRows();
                AddCountToBase(securityCountList, "I");
                GetDepartmentIndexValue(dic, securityCountList, weight, "fdKeyId", "");     //安全问题数量指标

                weight = GetConfig(config, "8");
                IList<EIRow> produceCountList = produceCount.GetRows();
                AddCountToBase(produceCountList, "I");
                GetDepartmentIndexValue(dic, produceCountList, weight, "fdKeyId", "");     //生产问题的数量指标

                weight = GetConfig(config, "9");
                IList<EIRow> producePlanRateList = producePlanRate.GetRows();
                AddCountToBase(producePlanRateList, "PLUS");
                GetDepartmentIndexValue(dic, producePlanRateList, weight, "fdRate", "PLUS");  //生产计划偏差率指标

                weight = GetConfig(config, "10");
                IList<EIRow> materialPlanRateRateList = materialPlanRate.GetRows();
                AddCountToBase(materialPlanRateRateList, "SUB");
                GetDepartmentIndexValue(dic, materialPlanRateRateList, weight, "fdRate", "SUB");  //材料计划超节率权重

                IList<EIRow> dest = (from it in dic where selectDepartments.Contains(it.Key) 
                                     select it.Value).ToList<EIRow>();

                //foreach (var item in dic.Values)
                foreach (var item in dest)
                {
                    ChartData cd = new ChartData(item["fdName"].ToString(), Convert.ToDecimal(item["fdValue"]) + 100);
                    lstIndex.Add(cd);
                }

                itemsSource.Add(lstIndex);
                Chart.ItemsSource = itemsSource;
                Chart.Visibility = System.Windows.Visibility.Visible;
            }
        }

        /// <summary>
        /// 将子单位的数据加到父单位中
        /// </summary>
        /// <param name="list"></param>
        /// <param name="type"></param>
        private void AddCountToBase(IList<EIRow> list, string type)
        {
            IList<EIRow> newCopy = new List<EIRow>();   //克隆一份新的List，传入的list的值会发生变化
            foreach (var element in list)
            {
                switch (type)
                {
                    case "I":
                        newCopy.Add(Common.CloneRow(element, new string[] { "fdKeyId", "fdDepartmentId", "displayName",
                                                                            "fdParentId"}));
                        break;
                    case "PLUS":
                    case "SUB":
                        newCopy.Add(Common.CloneRow(element, new string[] { "fdPlanSum", "fdActualSum", "fdRate", 
                                                                            "fdDepartmentId", "displayName","fdParentId"}));
                        break;
                    default:
                        break;
                }
            }

            foreach (var item in list)
            {
                if(Common.GetIntValue(item["fdDate"]) == 1)
                    AddUpToBase(item, newCopy, type);              
            }

            foreach (var v in list)
            {
                CalRate(v, type);
            }
        }

        /// <summary>
        /// 累加函数(递归调用)
        /// </summary>
        /// <param name="item"></param>
        /// <param name="list"></param>
        /// <param name="type"></param>
        private void AddUpToBase(EIRow item, IList<EIRow> list, string type)
        {
            string fdKeyId = item["fdDepartmentId"].ToString().Trim();
            var childItems = (from element in list
                              where (element["fdParentId"] != null) &&
                                  (element["fdParentId"].ToString().Trim().Equals(fdKeyId))
                              select element).ToList<EIRow>();

            IList<EIRow> newCopy = new List<EIRow>();   //克隆一份新的List，防止迭代时修改传入的list
            foreach (var element in childItems)
            {
                switch (type)
                {
                    case "I":
                        newCopy.Add(Common.CloneRow(element, new string[] { "fdKeyId", "fdDepartmentId", "displayName",
                                                                            "fdParentId"}));
                        break;
                    case "PLUS":
                    case "SUB":
                        newCopy.Add(Common.CloneRow(element, new string[] { "fdPlanSum", "fdActualSum", "fdRate", 
                                                                            "fdDepartmentId", "displayName", "fdParentId"}));
                        break;
                    default:
                        break;
                }
            }

            foreach (var it in childItems)
            {
                AddUpToBase(it, list, type);

                switch (type)
                {
                    case "I":
                        AddCount(item, it);
                        break;
                    case "PLUS":
                    case "SUB":
                        AddValue(item, it);
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// 累加安全/生产问题次数
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="child"></param>
        private void AddCount(EIRow dest, EIRow child)
        {
            int baseCount = Common.GetIntValue(dest["fdKeyId"]);
            int childCount = Common.GetIntValue(child["fdKeyId"]);
            dest.Add("fdKeyId", baseCount + childCount);
        }

        /// <summary>
        /// 累加计划量和实际量
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="child"></param>
        private void AddValue(EIRow dest, EIRow child)
        {
            double planValue = Common.GetDoubleValue(dest["fdPlanSum"]);
            double actualValue = Common.GetDoubleValue(dest["fdActualSum"]);
            double pValue = Common.GetDoubleValue(child["fdPlanSum"]);
            double aValue = Common.GetDoubleValue(child["fdActualSum"]);

            dest.Add("fdPlanSum", planValue + pValue);
            dest.Add("fdActualSum", actualValue + aValue);
        }

        /// <summary>
        /// 计算偏差率/超节率
        /// </summary>
        /// <param name="item"></param>
        private void CalRate(EIRow item, string type)
        {
            decimal fdPlanSum = Common.GetDecimalValue(item["fdPlanSum"]);
            decimal fdActualSum = Common.GetDecimalValue(item["fdActualSum"]);

            decimal result = Common.GetRate(fdActualSum, fdPlanSum);
            item.Add("fdRate", result);
        }

        /// <summary>
        /// 工程单位对比图，获取各个指标值*权重结果
        /// </summary>
        /// <param name="dic"></param>
        /// <param name="list"></param>
        /// <param name="weight"></param>
        /// <param name="index"></param>
        private void GetDepartmentIndexValue(IDictionary<string, EIRow> dic, IList<EIRow> list, decimal weight, string index ,string type)
        {
            foreach (var item in list)
            {
                if ((item["fdDepartmentId"] == null) || (item["fdDepartmentId"].ToString().Trim() == string.Empty) ||
                    (item["displayName"] == null) || (item["displayName"].ToString().Trim() == string.Empty))
                {
                    continue;
                }

                string fdDepartmentId = item["fdDepartmentId"].ToString().Trim();
                string fdName = item["displayName"].ToString().Trim();

                if (dic.ContainsKey(fdDepartmentId))
                {
                    EIRow row = dic[fdDepartmentId];
                    decimal val = GetDepartmentValue(item, index, weight, type);

                    row.Add("fdValue", Common.GetDecimalValue(row["fdValue"]) + val);
                }
                else
                {
                    dic.Add(fdDepartmentId, new EIRow());
                    EIRow row = dic[fdDepartmentId];
                    decimal val = GetDepartmentValue(item, index, weight, type);
                    row.Add("fdName", fdName);
                    row.Add("fdValue", val);
                }
            }
        }

        /// <summary>
        /// 计算各项指标值
        /// </summary>
        /// <param name="item"></param>
        /// <param name="index"></param>
        /// <param name="weight"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private decimal GetDepartmentValue(EIRow item, string index, decimal weight, string type)
        {
            decimal result = Decimal.Zero;

            if (index.Equals("fdKeyId"))
            {
                result += (Common.GetDecimalValue(item[index])*weight);
            }
            else if (index.Equals("fdRate"))
            {
                if (type.Equals("PLUS"))    //生产计划偏差率
                {
                    decimal actualSum = Common.GetDecimalValue(item["fdActualSum"]);
                    decimal planSum = Common.GetDecimalValue(item["fdPlanSum"]);

                    decimal val = planSum <= Decimal.Zero ? Decimal.Zero : (Math.Abs(1 - actualSum / planSum) * 100);
                    result += val * weight;
                }
                else if (type.Equals("SUB"))    //材料消耗超节率
                {
                    decimal actualSum = Common.GetDecimalValue(item["fdActualSum"]);
                    decimal planSum = Common.GetDecimalValue(item["fdPlanSum"]);

                    decimal val = planSum <= Decimal.Zero ? Decimal.Zero : (Math.Abs(actualSum / planSum - 1) * 100);
                    result += val * weight;
                }
            }

            return result;
        }

        #endregion

        #region 显示生产综合指标趋势分析图

        /// <summary>
        /// 初始化RadChart图
        /// </summary>
        /// <param name="titleIndex"></param>
        private void InitChart(string titleIndex)
        {
            switch (titleIndex)
            {
                case "TREND":
                    this.Chart.DefaultView.ChartTitle.Content = "生产综合指标趋势分析图";
                    break;
                case "DEPARTMENT":
                    this.Chart.DefaultView.ChartTitle.Content = "生产综合指标对比分析图";
                    break;
                default:
                    break;
            }

            this.Chart.DefaultView.ChartTitle.FontSize = Common.FontsizeSetting;
            this.Chart.DefaultView.ChartArea.FontSize = Common.FontsizeSetting;
            this.Chart.DefaultView.ChartLegend.FontSize = Common.FontsizeSetting;

            this.Chart.DefaultSeriesDefinition.ShowItemToolTips = true;
            this.Chart.DefaultSeriesDefinition.LegendDisplayMode = LegendDisplayMode.DataPointLabel;
            this.Chart.DefaultView.ChartLegend.Header = string.Empty;

            this.Chart.DefaultView.ChartArea.AxisX.LayoutMode = AxisLayoutMode.Inside;
            this.Chart.DefaultView.ChartArea.AxisX.AutoRange = true;
            this.Chart.DefaultView.ChartArea.AxisX.LabelRotationAngle = 45;
            this.Chart.DefaultView.ChartArea.AxisY.MajorGridLinesVisibility = Visibility.Visible;
            this.Chart.DefaultView.ChartArea.AxisY.MinorGridLinesVisibility = Visibility.Visible;
            this.Chart.DefaultView.ChartArea.AxisY.StripLinesVisibility = Visibility.Visible;
            this.Chart.DefaultView.ChartArea.AxisY.DefaultLabelFormat = Common.ChartDefaultLabelFormat;

            this.Chart.DefaultView.ChartArea.AdditionalYAxes.Clear();
            //this.Chart.DefaultView.ChartArea.AdditionalYAxes.Add(new AxisY());
            //this.Chart.DefaultView.ChartArea.AdditionalYAxes[0].AxisName = "Secondary";
            //this.Chart.DefaultView.ChartArea.AdditionalYAxes[0].Title = "完成率（%）";

            this.Chart.SeriesMappings.Clear();
            this.Chart.SeriesMappings.Add(GenerateSeries("综合指标", 0));
        }

        /// <summary>
        /// 生成柱状图定义
        /// </summary>
        /// <param name="label"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private SeriesMapping GenerateSeries(string label, int index)
        {
            SeriesMapping series = new SeriesMapping();
            BarSeriesDefinition definition = new BarSeriesDefinition();
            series.SeriesDefinition = definition;
            series.CollectionIndex = index;
            series.LegendLabel = label;

            series.SeriesDefinition.ShowItemLabels = false;
            series.SeriesDefinition.ShowItemToolTips = true;
            series.SeriesDefinition.ShowZeroValuesLabels = true;

            series.ItemMappings.Add(new ItemMapping("Date", DataPointMember.XCategory));
            series.ItemMappings.Add(new ItemMapping("DataValue", DataPointMember.YValue));

            series.SeriesDefinition.InteractivitySettings.HoverScope = InteractivityScope.Series;
            series.SeriesDefinition.InteractivitySettings.SelectionScope = InteractivityScope.Series;
            series.SeriesDefinition.InteractivitySettings.SelectionMode = ChartSelectionMode.Multiple;
            series.SeriesDefinition.ItemLabelFormat = Common.ChartItemLabelFormat;

            return series;
        }

        #endregion


    }
}
